﻿using System;
using System.Diagnostics;
using System.Linq;
using FluentValidation;
using LINQPad.OpenAccess.Settings;
using LINQPad.OpenAccess.UI.Services;

namespace LINQPad.OpenAccess.UI.ViewModel
{
    /// <summary>
    /// <see cref="ConnectionSettingsViewModel"/> for custom connections
    /// </summary>
    public class CustomConnectionSettingsViewModel : ConnectionSettingsViewModel<CustomConnectionSettingsViewModel>
    {
        /// <summary>
        /// The default name.
        /// </summary>
        public const string DefaultName = "custom";
        /// <summary>
        /// The default description.
        /// </summary>
        public const string DefaultDescription = "uses a custom connection string for the connection";

        #region Private

        #region - Vars

        [DebuggerBrowsable( DebuggerBrowsableState.Never )]
        private string _connectionString;
        [DebuggerBrowsable( DebuggerBrowsableState.Never )]
        private bool _encryptConnectionString;

        #endregion

        #endregion

        #region Public

        #region - Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="CustomConnectionSettingsViewModel" /> class.
        /// </summary>
        /// <param name="userInteractionService">The user interaction service.</param>
        /// <param name="validator">The validator.</param>
        public CustomConnectionSettingsViewModel( IUserInteractionService userInteractionService, IValidator<CustomConnectionSettingsViewModel> validator )
            : base( DefaultName, DefaultDescription, userInteractionService, validator ) { }

        #endregion

        #region - Properties

        /// <summary>
        /// Gets or sets a value indicating whether the connection string should be encrypted.
        /// </summary>
        /// <value>
        ///   <c>true</c> if the connection string should be encrypted; otherwise, <c>false</c>.
        /// </value>
        public bool EncryptConnectionString
        {
            get
            {
                return this._encryptConnectionString;
            }
            set
            {
                if ( this._encryptConnectionString != value )
                {
                    this._encryptConnectionString = value;
                    this.OnPropertyChanged( ( ) => this.EncryptConnectionString );
                }
            }
        }
        /// <summary>
        /// Gets a value indicating whether this instance has a connection string set.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance has a connection string set; otherwise, <c>false</c>.
        /// </value>
        public bool HasConnectionString
        {
            get
            {
                return !String.IsNullOrWhiteSpace( this._connectionString );
            }
        }
        /// <summary>
        /// Gets or sets the connection string.
        /// </summary>
        /// <value>
        /// The connection string.
        /// </value>
        public string ConnectionString
        {
            get
            {
                return this._connectionString;
            }
            set
            {
                if ( this._connectionString != value )
                {
                    this._connectionString = value;
                    this.OnPropertyChanged( ( ) => this.ConnectionString );
                    this.OnPropertyChanged( ( ) => this.HasConnectionString );
                    this.Invalidate( );
                }
            }
        }

        #endregion

        #endregion

        #region ConnectionSettingsViewModel Members

        /// <summary>
        /// Determines whether this instance can refresh.
        /// </summary>
        /// <returns>
        ///   <c>true</c> if this instance can refresh; otherwise, <c>false</c>.
        /// </returns>
        protected override bool CanRefresh( )
        {
            return false;
        }
        /// <summary>
        /// Determines whether the specified provider is supported.
        /// </summary>
        /// <param name="providerName">Name of the provider.</param>
        /// <returns>
        ///   <c>true</c> if the provider is supported; otherwise, <c>false</c>.
        /// </returns>
        public override bool IsProviderSupported( string providerName )
        {
            return true;
        }
        /// <summary>
        /// Called to actually load the view model's settings.
        /// </summary>
        protected override void DoLoadSettings( )
        {
            var connectionString = this.ConnectionInfo.DatabaseInfo.CustomCxString;
            if ( this.ConnectionInfo.DatabaseInfo.EncryptCustomCxString && !String.IsNullOrWhiteSpace( connectionString ) )
            {
                connectionString = this.ConnectionInfo.Decrypt( connectionString );
                this.EncryptConnectionString = true;
            }

            this.ConnectionString = connectionString;
        }
        /// <summary>
        /// Called to actually write the view model's settings.
        /// </summary>
        protected override void DoWriteSettings( )
        {
            var connectionString = this.ConnectionString;
            if ( !String.IsNullOrWhiteSpace( connectionString ) && this.EncryptConnectionString )
                connectionString = this.ConnectionInfo.Encrypt( connectionString );

            this.DriverSettings.Connection = new ConnectionSettings( ); // reset old settings
            this.ConnectionInfo.DatabaseInfo.EncryptCustomCxString = this.EncryptConnectionString;
            this.ConnectionInfo.DatabaseInfo.CustomCxString = connectionString;
        }
        /// <summary>
        /// Refreshes this instance.
        /// </summary>
        public override void Refresh( )
        {

        }

        #endregion
    }
}
